from flask import Flask, render_template, request, redirect, url_for, session
import os
from utils import load_data, save_data, export_to_csv
from werkzeug.security import generate_password_hash
from db import get_db_connection
from flask import jsonify

app = Flask(__name__)
app.secret_key = 'your_secret_key'  # 用于 Session 加密
from customer_routes import customer_bp
app.register_blueprint(customer_bp)

from flask import Flask, render_template, request, redirect, url_for, session
import time, random, re
import pymysql

# 加载客户信息（这个是你缺的）
def load_customers_from_db():
    conn = get_db_connection()
    try:
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            cursor.execute("SELECT * FROM userInfo")
            customers = cursor.fetchall()
            return customers
    finally:
        conn.close()


# 用于短信验证码的全局状态
current_code = ''
code_time = 0
code_expire = 300  # 秒
wrong_attempts = 0
lockout_until = 0
last_register_code_time = 0
last_login_code_time = 0


# 手机号/身份证校验
PHONE_REGEX = r'^1[3-9]\d{9}$'
PID_REGEX = r'^\d{17}[\dXx]$'

DB_CONFIG = {
    'host': 'localhost',
    'user': 'root',
    'password': '200412',
    'database': 'keshe',
    'port': 3306,
    'charset': 'utf8mb4'
}
# 数据目录路径
data_dir = os.path.join(os.path.dirname(__file__), 'data')

# ------------------------ 登录系统 ------------------------

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form.get('username', '').strip()
        password = request.form.get('password', '').strip()
        if username == 'admin' and password == 'admin123':
            session.pop('_flashes', None)
            session['user'] = username
            session['role'] = 'admin'
            return redirect('/admin/dashboard')
        else:
            return render_template('login.html', error='用户名或密码错误')

    session.pop('_flashes', None)
    return render_template('login.html')


@app.route('/logout')
def logout():
    session.clear()
    return redirect('/login')

@app.route('/admin/dashboard')
def admin_dashboard():
    if session.get('role') != 'admin':
        return redirect('/login')
    return render_template('admin_dashboard.html')

@app.route('/customer/dashboard')
def customer_dashboard():
    if session.get('role') != 'customer':
        return redirect('/login')
    return render_template('customer_dashboard.html')


# ------------------------ 发送验证码（登录/注册） ------------------------
@app.route('/send_sms_code', methods=['GET'])
def send_sms_code():
    global current_code, code_time, last_register_code_time, last_login_code_time
    global wrong_attempts, lockout_until

    phone = request.args.get('phone', '').strip()
    mode = request.args.get('mode', 'login')  # 默认为登录模式
    pid = request.args.get('pid', '').strip()

    if not re.match(PHONE_REGEX, phone):
        return "手机号格式错误"

    now = time.time()

    if now < lockout_until:
        return f"账号已锁定，请等待 {int((lockout_until - now) // 60) + 1} 分钟后再试"

    # ❗ 这里根据 mode 判断冷却时间
    if mode == 'register':
        if last_register_code_time and now - last_register_code_time < 60:
            return f"注册验证码发送过于频繁，请等待 {60 - int(now - last_register_code_time)} 秒"
    else:
        if last_login_code_time and now - last_login_code_time < 60:
            return f"登录验证码发送过于频繁，请等待 {60 - int(now - last_login_code_time)} 秒"

    try:
        conn = pymysql.connect(**DB_CONFIG, cursorclass=pymysql.cursors.DictCursor)
        cursor = conn.cursor()

        cursor.execute("SELECT customerName FROM userInfo WHERE telephone=%s", (phone,))
        result = cursor.fetchone()
        conn.close()

        if mode == 'login' and not result:
            return "账号不存在，请先注册"

        if mode == 'register':
            if result:
                return "该手机号已注册，请直接登录"
            if not pid or not re.match(PID_REGEX, pid):
                return "请填写正确的身份证号"

        # ✅ 生成验证码
        current_code = str(random.randint(100000, 999999))
        code_time = now
        wrong_attempts = 0

        # ✅ 分别记录冷却时间
        if mode == 'register':
            last_register_code_time = now
        else:
            last_login_code_time = now

        session['sms_code'] = current_code
        session['sms_code_phone'] = phone
        session['sms_code_time'] = now

        return f"验证码已发送：{current_code}（5分钟内有效）"

    except Exception as e:
        return f"数据库错误：{str(e)}"


# ------------------------ 短信验证码登录 ------------------------

# 手机号+验证码登录客户
@app.route('/login_sms', methods=['GET', 'POST'])
def login_sms():
    if request.method == 'GET':
        # 访问登录页面，返回 html
        return render_template('login_sms.html')

    # 处理登录请求（POST）
    global wrong_attempts, lockout_until, current_code, code_time

    phone = request.form.get('phone', '').strip()
    code = request.form.get('code', '').strip()

    if not phone or not code:
        return jsonify({'status': 'error', 'message': '请输入手机号和验证码'})

    if not re.match(PHONE_REGEX, phone):
        return jsonify({'status': 'error', 'message': '手机号格式错误'})

    now = time.time()

    if now < lockout_until:
        return jsonify({'status': 'error', 'message': '账号已锁定，请5分钟后再试'})

    if now - code_time > code_expire:
        return jsonify({'status': 'error', 'message': '验证码已过期'})

    if code != current_code:
        wrong_attempts += 1
        if wrong_attempts >= 5:
            lockout_until = now + 300
            return jsonify({'status': 'error', 'message': '错误次数过多，账号已锁定'})
        else:
            return jsonify({'status': 'error', 'message': f'验证码错误（剩余尝试：{5 - wrong_attempts}次）'})

    try:
        conn = pymysql.connect(**DB_CONFIG, cursorclass=pymysql.cursors.DictCursor)
        cursor = conn.cursor()
        cursor.execute("SELECT customerID, customerName FROM userInfo WHERE telephone=%s", (phone,))
        result = cursor.fetchone()
        conn.close()

        if not result:
            return jsonify({'status': 'error', 'message': '账号不存在'})

        session['user'] = result['customerID']  # result 是字典，可以直接用字符串键
        session['role'] = 'customer'
        return jsonify({'status': 'success', 'message': f'欢迎回来，{result["customerName"]}！',
                        'redirect_url': '/customer/dashboard'})



    except Exception as e:
        return jsonify({'status': 'error', 'message': f'登录失败：{str(e)}'})



# ------------------------ 短信验证码注册 ------------------------

@app.route('/register_sms', methods=['GET', 'POST'])
def register_sms():
    if request.method == 'GET':
        return render_template('register_sms.html')

    try:
        print("收到注册请求，表单数据:", request.form)

        name = request.form.get('name', '').strip()
        pid = request.form.get('pid', '').strip().upper()
        phone = request.form.get('phone', '').strip()
        address = request.form.get('address', '').strip()
        code = request.form.get('code', '').strip()

        if not all([name, pid, phone, code]):
            return jsonify({'status': 'error', 'message': '请填写完整信息'})

        if not re.match(PHONE_REGEX, phone):
            return jsonify({'status': 'error', 'message': '手机号格式不正确'})
        if not re.match(PID_REGEX, pid):
            return jsonify({'status': 'error', 'message': '身份证格式不正确'})

        if 'sms_code' not in session or 'sms_code_phone' not in session or 'sms_code_time' not in session:
            return jsonify({'status': 'error', 'message': '请先获取验证码'})

        if session['sms_code_phone'] != phone:
            return jsonify({'status': 'error', 'message': '手机号与验证码不匹配'})

        if time.time() - session['sms_code_time'] > code_expire:
            return jsonify({'status': 'error', 'message': '验证码已过期'})

        if code != session['sms_code']:
            return jsonify({'status': 'error', 'message': '验证码错误'})

        conn = pymysql.connect(**DB_CONFIG)
        cursor = conn.cursor()

        cursor.execute("SELECT * FROM userInfo WHERE telephone=%s OR PID=%s", (phone, pid))
        if cursor.fetchone():
            conn.close()
            return jsonify({'status': 'error', 'message': '手机号或身份证已被注册'})

        cursor.execute(
            "INSERT INTO userInfo (customerName, PID, telephone, address) VALUES (%s, %s, %s, %s)",
            (name, pid, phone, address or None)
        )
        conn.commit()
        conn.close()

        return jsonify({'status': 'success', 'message': '注册成功，请登录'})

    except Exception as e:
        print("注册异常:", str(e))
        return jsonify({'status': 'error', 'message': f'注册失败：{str(e)}'})

# ------------------------ 首页 ------------------------
@app.route('/')
def index():
    # 如果已登录，根据角色跳转到对应页面
    if 'role' in session:
        if session['role'] == 'admin':
            return redirect(url_for('admin_dashboard'))  # 管理员主页
        elif session['role'] == 'customer':
            return redirect(url_for('customer_dashboard'))  # 客户主页（customerID 存在 session['user'] 中）
    return redirect(url_for('login'))  # 未登录用户跳转到登录页

# ------------------------ 客户管理 ------------------------
@app.route('/customers')
def customers():
    # 从数据库中加载客户列表（应读取 userInfo 表）
    customers = load_customers_from_db()  # 返回列表，每项为 {customerID, customerName, PID, telephone, address}

    # 原始模糊搜索（跨多个字段）
    query = request.args.get('q', '').strip()

    # 高级查询参数（字段+模式+值）
    mode = request.args.get('mode', '').strip()     # 查询模式（exact, fuzzy, range）
    field = request.args.get('field', '').strip()   # 要查询的字段（如 telephone）
    value = request.args.get('value', '').strip()   # 精确/模糊的值
    low = request.args.get('low', '').strip()       # 范围查询：下限
    high = request.args.get('high', '').strip()     # 范围查询：上限

    # ---------------- 高级查询 ----------------
    if field and mode:
        if mode == 'exact':
            customers = [c for c in customers if c.get(field, '') == value]
        elif mode == 'fuzzy':
            customers = [c for c in customers if value in c.get(field, '')]
        elif mode == 'range':
            customers = [c for c in customers if low <= c.get(field, '') <= high]

    # ---------------- 模糊搜索（兼容旧版查询） ----------------
    elif query:
        customers = [
            c for c in customers
            if query in c.get('customerID', '')         # ✅ 客户编号
            or query in c.get('customerName', '')       # ✅ 姓名
            or query in c.get('PID', '')                # ✅ 身份证
            or query in c.get('telephone', '')          # ✅ 电话
            or query in c.get('address', '')            # ✅ 地址
        ]

    # 返回模板，展示客户列表和查询参数
    return render_template(
        'customers.html',
        customers=customers,
        query=query,
        mode=mode,
        field=field,
        value=value,
        low=low,
        high=high
    )

@app.route('/customers/add', methods=['GET', 'POST'])
def add_customer():
    if request.method == 'POST':
        customerName = request.form['customerName'].strip()
        PID = request.form['PID'].strip().upper()
        telephone = request.form['telephone'].strip()
        address = request.form['address'].strip()

        conn = get_db_connection()
        try:
            with conn.cursor() as cursor:
                cursor.execute("""
                    INSERT INTO userInfo (customerName, PID, telephone, address)
                    VALUES (%s, %s, %s, %s)
                """, (customerName, PID, telephone, address))
            conn.commit()
            return redirect(url_for('customers'))  # ✅ 自动触发开户
        except Exception as e:
            conn.rollback()
            return f"添加失败：{e}"
        finally:
            conn.close()

    return render_template('add_customer.html', customer=None)



@app.route('/customers/edit/<id>', methods=['GET', 'POST'])
def edit_customer(id):
    conn = get_db_connection()
    try:
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            cursor.execute("SELECT * FROM userInfo WHERE customerID = %s", (id,))
            customer = cursor.fetchone()
            if not customer:
                return '客户不存在', 404

            if request.method == 'POST':
                customerName = request.form['customerName'].strip()
                PID = request.form['PID'].strip().upper()
                telephone = request.form['telephone'].strip()
                address = request.form['address'].strip()

                cursor.execute("""
                    UPDATE userInfo
                    SET customerName = %s, PID = %s, telephone = %s, address = %s
                    WHERE customerID = %s
                """, (customerName, PID, telephone, address, id))
                conn.commit()
                return redirect(url_for('customers'))

        return render_template('edit_customer.html', customer=customer)
    except Exception as e:
        conn.rollback()
        return f"修改失败：{e}"
    finally:
        conn.close()


@app.route('/customers/delete/<id>')
def delete_customer(id):
    conn = get_db_connection()
    try:
        with conn.cursor() as cursor:
            cursor.execute("DELETE FROM userInfo WHERE customerID = %s", (id,))
        conn.commit()
        return redirect(url_for('customers'))
    except Exception as e:
        conn.rollback()
        return f"删除失败：{e}"
    finally:
        conn.close()



@app.route('/customers/export')
def export_customers():
    conn = get_db_connection()
    try:
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            cursor.execute("SELECT customerID, customerName, PID, telephone, address FROM userInfo")
            customers = cursor.fetchall()
    except Exception as e:
        return f"导出失败：{e}"
    finally:
        conn.close()

    # 导出为 CSV
    csv_path = os.path.join(data_dir, 'customers_export.csv')
    export_to_csv(customers, ['customerID', 'customerName', 'PID', 'telephone', 'address'], csv_path)
    return redirect(url_for('customers'))

# ------------------------ 银行卡管理 ------------------------
@app.route('/cards')
def cards():
    mode = request.args.get('mode', '').strip()
    field = request.args.get('field', '').strip()
    value = request.args.get('value', '').strip()
    low = request.args.get('low', '').strip()
    high = request.args.get('high', '').strip()
    error = None
    cards = []

    valid_fields = ['cardID', 'curID', 'openDate', 'openMoney', 'balance', 'pass', 'IsReportLoss', 'customerID']

    if field and field not in valid_fields:
        return "查询字段不合法"

    try:
        conn = get_db_connection()
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            base_sql = "SELECT * FROM cardInfo"
            where_clause = ""
            params = []

            if field and mode:
                if field == 'IsReportLoss' and mode != 'exact':
                    error = "查询失败：是否挂失字段仅支持精确查询（是/否）"
                else:
                    if mode == 'exact':
                        where_clause = f"WHERE {field} = %s"
                        params = [value]
                    elif mode == 'fuzzy':
                        where_clause = f"WHERE {field} LIKE %s"
                        params = [f"%{value}%"]
                    elif mode == 'range':
                        where_clause = f"WHERE {field} BETWEEN %s AND %s"
                        params = [low, high]

            final_sql = f"{base_sql} {where_clause}"
            cursor.execute(final_sql, params)
            cards = cursor.fetchall()

    except Exception as e:
        return f"查询失败：{str(e)}"
    finally:
        conn.close()

    return render_template(
        'cards.html',
        cards=cards,
        mode=mode,
        field=field,
        value=value,
        low=low,
        high=high,
        error=error
    )


@app.route('/cards/add', methods=['GET', 'POST'])
def add_card():
    conn = get_db_connection()
    try:
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            if request.method == 'POST':
                cardID = request.form['cardID']
                curID = request.form.get('curID', 'RMB')  # 默认人民币
                openDate = request.form['openDate']
                openMoney = float(request.form['openMoney'])
                balance = float(request.form['balance'])
                password = request.form['pass']
                is_lost = '是' if request.form.get('IsReportLoss') == 'on' else '否'
                customerID = request.form['customerID']

                cursor.execute("""
                    INSERT INTO cardInfo (cardID, curID, openDate, openMoney, balance, pass, IsReportLoss, customerID)
                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
                """, (cardID, curID, openDate, openMoney, balance, password, is_lost, customerID))
                conn.commit()
                return redirect(url_for('cards'))

            # 获取客户信息供选择
            cursor.execute("SELECT customerID, customerName FROM userInfo")
            customers = cursor.fetchall()
            return render_template('add_card.html', customers=customers, card=None)

    except Exception as e:
        conn.rollback()
        return f"添加银行卡失败：{e}"
    finally:
        conn.close()


@app.route('/cards/edit/<card_id>', methods=['GET', 'POST'])
def edit_card(card_id):
    conn = get_db_connection()
    try:
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            cursor.execute("SELECT * FROM cardInfo WHERE cardID = %s", (card_id,))
            card = cursor.fetchone()
            if not card:
                return '卡片不存在', 404

            if request.method == 'POST':
                curID = request.form.get('curID', 'RMB')
                openDate = request.form['openDate']
                openMoney = float(request.form['openMoney'])
                balance = float(request.form['balance'])
                password = request.form['pass']
                is_lost = '是' if request.form.get('IsReportLoss') == 'on' else '否'
                customerID = request.form['customerID']

                cursor.execute("""
                    UPDATE cardInfo
                    SET curID=%s, openDate=%s, openMoney=%s, balance=%s, pass=%s, IsReportLoss=%s, customerID=%s
                    WHERE cardID=%s
                """, (curID, openDate, openMoney, balance, password, is_lost, customerID, card_id))
                conn.commit()
                return redirect(url_for('cards'))

            # 取客户列表供选择
            cursor.execute("SELECT customerID, customerName FROM userInfo")
            customers = cursor.fetchall()
            return render_template('edit_card.html', card=card, customers=customers)

    except Exception as e:
        conn.rollback()
        return f"修改银行卡失败：{e}"
    finally:
        conn.close()


@app.route('/cards/delete/<card_id>')
def delete_card(card_id):
    conn = get_db_connection()
    try:
        with conn.cursor() as cursor:
            cursor.execute("DELETE FROM cardInfo WHERE cardID = %s", (card_id,))
        conn.commit()
        return redirect(url_for('cards'))
    except Exception as e:
        conn.rollback()
        return f"删除失败：{e}"
    finally:
        conn.close()


@app.route('/cards/export')
def export_cards():
    conn = get_db_connection()
    try:
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            cursor.execute("SELECT * FROM cardInfo")
            cards = cursor.fetchall()

        # 字段按数据库字段名导出
        export_to_csv(cards, [
            'cardID', 'curID', 'openDate', 'openMoney', 'balance',
            'pass', 'IsReportLoss', 'customerID'
        ], os.path.join(data_dir, 'cards_export.csv'))

        return redirect(url_for('cards'))
    except Exception as e:
        return f"导出失败：{e}"


@app.route('/cards/reset_pass/<card_id>', methods=['GET', 'POST'])
def reset_card_password(card_id):
    if session.get('role') != 'admin':
        return redirect('/login')

    conn = get_db_connection()
    try:
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            cursor.execute("SELECT * FROM cardInfo WHERE cardID = %s", (card_id,))
            card = cursor.fetchone()
            if not card:
                return '卡片不存在', 404

            message = ''
            if request.method == 'POST':
                new_password = request.form['new_password']
                confirm_password = request.form['confirm_password']
                if new_password != confirm_password:
                    message = '两次密码输入不一致'
                else:
                    # 可以选择加密或不加密（以下为不加密存储）
                    cursor.execute("UPDATE cardInfo SET pass = %s WHERE cardID = %s", (new_password, card_id))
                    conn.commit()
                    message = '密码已成功重置！'

            return render_template('reset_card_password.html', card=card, message=message)
    except Exception as e:
        conn.rollback()
        return f"重置密码失败：{e}"
    finally:
        conn.close()

# ------------------------ 存款业务管理 ------------------------
@app.route('/deposits')
def deposits():
    conn = get_db_connection()
    try:
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            query_sql = "SELECT * FROM deposit"
            filters = []
            params = []

            # 获取查询参数
            mode = request.args.get('mode', '').strip()
            field = request.args.get('field', '').strip()
            value = request.args.get('value', '').strip()
            low = request.args.get('low', '').strip()
            high = request.args.get('high', '').strip()
            error = None

            # 字段名白名单（防止 SQL 注入）
            valid_fields = ['savingID', 'savingName', 'descrip']

            if field and field not in valid_fields:
                return "无效字段"

            # 构造 SQL 条件
            if field and mode:
                if mode == 'exact':
                    filters.append(f"{field} = %s")
                    params.append(value)
                elif mode == 'fuzzy':
                    filters.append(f"{field} LIKE %s")
                    params.append(f"%{value}%")
                elif mode == 'range':
                    filters.append(f"{field} BETWEEN %s AND %s")
                    params.extend([low, high])

            if filters:
                query_sql += " WHERE " + " AND ".join(filters)

            cursor.execute(query_sql, tuple(params))
            deposits = cursor.fetchall()

            return render_template(
                'deposits.html',
                deposits=deposits,
                mode=mode,
                field=field,
                value=value,
                low=low,
                high=high,
                error=error
            )
    except Exception as e:
        return f"查询失败：{e}"
    finally:
        conn.close()


@app.route('/deposits/add', methods=['GET', 'POST'])
def add_deposit():
    if request.method == 'POST':
        savingID = request.form['savingID']
        savingName = request.form['savingName']
        descrip = request.form['descrip']

        conn = get_db_connection()
        try:
            with conn.cursor() as cursor:
                cursor.execute("""
                    INSERT INTO deposit (savingID, savingName, descrip)
                    VALUES (%s, %s, %s)
                """, (savingID, savingName, descrip))
            conn.commit()
            return redirect(url_for('deposits'))
        except Exception as e:
            conn.rollback()
            return f"添加失败：{e}"
        finally:
            conn.close()

    return render_template('add_deposit.html', deposit=None)


@app.route('/deposits/edit/<savingID>', methods=['GET', 'POST'])
def edit_deposit(savingID):
    conn = get_db_connection()
    try:
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            cursor.execute("SELECT * FROM deposit WHERE savingID = %s", (savingID,))
            deposit = cursor.fetchone()
            if not deposit:
                return "业务不存在", 404

            if request.method == 'POST':
                savingName = request.form['savingName']
                descrip = request.form['descrip']

                cursor.execute("""
                    UPDATE deposit
                    SET savingName = %s, descrip = %s
                    WHERE savingID = %s
                """, (savingName, descrip, savingID))
                conn.commit()
                return redirect(url_for('deposits'))

        return render_template('add_deposit.html', deposit=deposit)
    except Exception as e:
        conn.rollback()
        return f"修改失败：{e}"
    finally:
        conn.close()

@app.route('/deposits/delete/<savingID>')
def delete_deposit(savingID):
    conn = get_db_connection()
    try:
        with conn.cursor() as cursor:
            cursor.execute("DELETE FROM deposit WHERE savingID = %s", (savingID,))
        conn.commit()
        return redirect(url_for('deposits'))
    except Exception as e:
        conn.rollback()
        return f"删除失败：{e}"
    finally:
        conn.close()


@app.route('/deposits/export')
def export_deposits():
    conn = get_db_connection()
    try:
        with conn.cursor(pymysql.cursors.DictCursor) as cursor:
            cursor.execute("SELECT savingID, savingName, descrip FROM deposit")
            deposits = cursor.fetchall()

        export_to_csv(
            deposits,
            ['savingID', 'savingName', 'descrip'],
            os.path.join(data_dir, 'deposits_export.csv')
        )
        return redirect(url_for('deposits'))
    except Exception as e:
        return f"导出失败：{e}"
    finally:
        conn.close()

# ------------------------ 交易管理 -----------------------
@app.route('/transactions')
def transactions():
    tradeInfo = load_data(os.path.join(data_dir, 'transactions.json'))
    return render_template('transactions.html', tradeInfo=tradeInfo)

@app.route('/transactions/add', methods=['GET', 'POST'])
def add_transaction():
    if request.method == 'POST':
        cardID = request.form['cardID']
        tradeMoney = float(request.form['tradeMoney'])  # ✅ 金额字段
        tradeType = request.form['tradeType']           # ✅ 类型字段
        remark = request.form['remark']                 # ✅ 备注字段
        tradeDate = request.form['tradeDate']           # ✅ 日期字段

        cards = load_data(os.path.join(data_dir, 'cards.json'))
        card = next((c for c in cards if c['cardID'] == cardID), None)

        if not card:
            return '卡号不存在', 400

        beforeAmount = float(card['balance'])  # ✅ 用于显示前后余额（非主字段）

        if tradeType == '存款':
            afterAmount = beforeAmount + tradeMoney
        elif tradeType == '取款':
            if tradeMoney > beforeAmount:
                return '余额不足，无法取款', 400
            afterAmount = beforeAmount - tradeMoney
        else:
            return '交易类型错误', 400

        # 更新卡余额
        card['balance'] = afterAmount
        save_data(os.path.join(data_dir, 'cards.json'), cards)

        # 新交易记录（tradeInfo 格式）
        new_trade = {
            "tradeDate": tradeDate,
            "tradeType": tradeType,
            "tradeMoney": tradeMoney,
            "cardID": cardID,
            "beforeAmount": beforeAmount,
            "afterAmount": afterAmount,
            "remark": remark
        }

        tradeInfo = load_data(os.path.join(data_dir, 'transactions.json'))
        tradeInfo.append(new_trade)
        save_data(os.path.join(data_dir, 'transactions.json'), tradeInfo)

        return redirect(url_for('transactions'))

    cards = load_data(os.path.join(data_dir, 'cards.json'))
    return render_template('add_transaction.html', trade=None, cards=cards)  # ✅ 模板变量 trade


@app.route('/transactions/delete/<int:index>')
def delete_transaction(index):
    tradeInfo = load_data(os.path.join(data_dir, 'transactions.json'))
    if 0 <= index < len(tradeInfo):
        tradeInfo.pop(index)
        save_data(os.path.join(data_dir, 'transactions.json'), tradeInfo)
    return redirect(url_for('transactions'))


@app.route('/transactions/export')
def export_transactions():
    tradeInfo = load_data(os.path.join(data_dir, 'transactions.json'))
    export_to_csv(tradeInfo,
        ['tradeDate', 'tradeType', 'cardID', 'beforeAmount', 'tradeMoney', 'afterAmount', 'remark'],
        os.path.join(data_dir, 'transactions_export.csv')
    )
    return redirect(url_for('transactions'))


# ------------------------ 运行应用 ------------------------
if __name__ == '__main__':
    app.run(debug=True)